home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-09-16 | 42.8 KB | 1,092 lines | [TEXT/CCL2] |
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;; dialog-editor.lisp
- ;;
- ;;
- ;; ©1989,1990,1991 Apple Computer, Inc
- ;;
- ;; the main code of the dialog-editor portion of the interface designer
- ;;
-
- ;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; Change History
- ;;
- ;; 04/28/93 mwp Release
- ;; 07/22/92 bill Luke Hohmann's view-key-event-handler
- ;; 04/08/92 bill make sloppy-find-view-containing-point search from front to back.
- ;; -------------- 2.0
- ;; 01/09/91 alice put back cut etal:around methods, update edit-menu in select-and-add-xx -??????
- ;; select-all was broken
- ;; 12/29/91 alice window-do-operation has another argument
- ;; 12/18/91 bill prevent errors in remove-editable-dialog-item
- ;; ------------- 2.0b4
- ;; 11/05/91 bill nuke nfunction
- ;; 10/15/91 alice remove window-can-undo-p, add window-can-do-operation.
- ;; Advise window-do-operation to do cut etal inline instead of via
- ;; :around methods because there are no longer any methods for them to be :around.
- ;; 09/23/91 bill #'(setf view-nick-name) -> #'set-view-nick-name
- ;; 09/09/91 bill show item-palette only after adding subviews
- ;; 09/06/91 bill autosize the item-palette, (use-dialogs) on close-box click in item-palette
- ;; 08/12/91 alice lets not die in select-all;;
- ;; 07/26/91 bill WINDOW-CAN-UNDO-p was mis-parenthesized, CLEAR was brain-damaged
- ;; GROW-ITEM-OUTLINE needed to constain mouse movement
- ;; 02/07/91 bill move-selected-dialog-items fixed for user dragging outside of window
- ;; *2.0b1*
- ;; 01/30/91 bill select-and-add-dialog-item takes a mouse-pos parameter and
- ;; shows an outline on all monitors.
- ;;
-
- (in-package :interface-tools)
-
- ;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; misc
- ;;
-
- (proclaim '(special *dialog-change-undohook* *selected-dialog-items*
- *dialog-item-scrap* *grow-cursor*))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; variables & classes
- ;;
-
-
- (defvar *guide-gravity* 3
- "how far you can be from a guide to still snap to it")
-
- (defclass window-type-r-b (radio-button-dialog-item)
- ((attribute :initarg :attribute :accessor dialog-item-attribute)))
-
- (defclass frame-window-r-b (window-type-r-b)
- ())
-
- (defclass box-window-r-b (window-type-r-b)
- ())
-
- (defclass dialog-editor (non-editable-dialog)
- ((edited-dialog :initarg :dialog :accessor dialog-editor-dialog))
- (:default-initargs :window-type :document
- :view-position '(:top 100)
- :view-size #@(372 68)
- :window-show nil
- :close-box-p nil)
- )
-
- (defvar *prototype-dialog-items* '())
-
- (defvar *current-item-palette* nil)
-
- (defparameter *item-palette-size* #@(150 100))
-
- (defparameter *item-palette-position* (make-point (min (+ (point-h *item-palette-size*)
- (truncate *screen-width* 2))
- (- *screen-width*
- (point-h *item-palette-size*)))
- 70))
-
-
- (defclass item-palette (windoid non-editable-dialog)
- ())
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; definitions and redefinitions for the *dialog* class
- ;;
-
- (defmacro get-window-type (window)
- `(view-get ,window 'window-type))
-
- (defmacro get-vertical-guides (window)
- `(view-get ,window 'vertical-guides))
-
- (defmacro get-horizontal-guides (window)
- `(view-get ,window 'horizontal-guides))
-
- (defmethod initialize-instance :around ((window window) &key
- window-type)
- (declare (dynamic-extent initargs))
- (prog1
- (call-next-method)
- (setf (get-window-type window) window-type)
- (setf (get-vertical-guides window) ())
- (setf (get-horizontal-guides window) ())))
-
- (defmethod window-update-cursor :around ((window window) where)
- (declare (ignore where))
- (if (ccl::editing-dialogs-p window)
- (set-cursor (if (command-key-p)
- *grow-cursor*
- *cross-hair-cursor*))
- (call-next-method)))
-
- (defmethod view-draw-contents :around ((window window))
- (call-next-method)
- (when (ccl::editing-dialogs-p window)
- (draw-dialog-guides window)
- (highlight-selected-items window t t)))
-
- (defmethod view-deactivate-event-handler :around ((window window))
- (call-next-method)
- (setq *dialog-change-undohook* nil)
- (when *selected-dialog-items*
- (reset-selected-item-list window)))
-
- (defun sloppy-find-view-containing-point (view point slop)
- (let* ((views (view-subviews view)))
- (do* ((i (1- (length views)) (1- i))
- subview)
- ((< i 0))
- (setq subview (aref views i))
- (let* ((tl (view-position subview))
- (br (add-points tl (view-size subview)))
- (top (ccl::%i- (point-v tl) slop))
- (bottom (ccl::%i+ (point-v br) slop))
- (left (ccl::%i- (point-h tl) slop))
- (right (ccl::%i+ (point-h br) slop))
- (h (point-h point))
- (v (point-v point)))
- (when (and (ccl::%i<= top v)
- (ccl::%i<= v bottom)
- (ccl::%i<= left h)
- (ccl::%i<= h right))
- (return subview))))))
-
- (defmethod view-click-event-handler :around ((window window) where &aux
- (move-p (ccl::editing-dialogs-p window))
- (item (sloppy-find-view-containing-point
- window where 3)))
- (setq *dialog-change-undohook* nil)
- (if move-p
- (with-focused-view window
- (cond ((command-key-p)
- (grow-or-move-window window where))
- ((or (memq (point-h where) (get-vertical-guides window))
- (memq (point-v where) (get-horizontal-guides window)))
- (drag-guide window where))
- (item
- ;move, resize, or edit the item
- (if (double-click-p)
- (edit-dialog-item item)
- (let ((was-selected (dialog-item-selected-p item)))
- (if (shift-key-p)
- (grow-or-move-dialog-item window where item was-selected)
- (progn
- (unless was-selected
- (reset-selected-item-list window))
- (grow-or-move-dialog-item window where item nil))))))
- (t (select-several-items window where))))
- (call-next-method)))
-
- (defmethod view-key-event-handler :around ((window window) char)
- (if (and (ccl::editing-dialogs-p window)
- (member char '(#\UpArrow #\ForwardArrow #\BackArrow #\DownArrow)))
- (with-focused-view window
- (dolist (item *selected-dialog-items*)
- (highlight-one-selected-item window item t nil)
- (set-view-position
- item
- (case char
- (#\UpArrow (add-points (view-position item) #@(0 -1)))
- (#\ForwardArrow (add-points (view-position item) #@(1 0)))
- (#\BackArrow (add-points (view-position item) #@(-1 0)))
- (#\DownArrow (add-points (view-position item) #@(0 1)))))
- (highlight-one-selected-item window item t t)))
- (call-next-method)))
-
- ;;;;;;;;;;;
- ;;
- ;; cut/copy/paste/clear/select-all
- ;;
-
-
- (defmethod copy-selected-dialog-items ((window window))
- (mapcar #'(lambda (item)
- (copy-instance item))
- *selected-dialog-items*))
-
-
- (defmethod cut :around ((window window))
- (if (ccl::editing-dialogs-p window)
- (progn (setq *dialog-item-scrap* *selected-dialog-items*)
- (clear window))
- (when (next-method-p)(call-next-method))))
-
- (defmethod copy :around ((window window))
- (if (ccl::editing-dialogs-p window)
- (setq *dialog-item-scrap* (copy-selected-dialog-items window))
- (when (next-method-p)(call-next-method))))
-
- (defmethod paste :around ((window window))
- (if (ccl::editing-dialogs-p window)
- (let ((items *dialog-item-scrap*))
- (if items
- (progn
- (setq *dialog-change-undohook*
- (cons "Undo Paste"
- #'(lambda ()
- (apply
- #'remove-subviews window items)
- (setq *dialog-item-scrap* items
- *dialog-change-undohook* nil))))
- (apply
- #'add-subviews window items)
- (setq *dialog-item-scrap* ()))
- (message-dialog "No items to paste!")))
- (call-next-method)))
-
- (defmethod clear :around ((window window))
- (if (ccl::editing-dialogs-p window)
- (let* ((items *selected-dialog-items*))
- (if items
- (progn
- (setq *dialog-change-undohook*
- (cons "Undo Clear"
- #'(lambda ()
- (reset-selected-item-list window)
- (apply
- #'add-subviews window items)
- (dolist (item items)
- (select-dialog-item window item))
- (setq *dialog-change-undohook* nil))))
- (apply
- #'remove-subviews window items))
- (message-dialog "No items to remove!")))
- (when (next-method-p)(call-next-method))))
-
- (defmethod select-all :around ((window window))
- (if (ccl::editing-dialogs-p window)
- (dolist (item (dialog-items window))
- (select-dialog-item window item))
- (when (next-method-p)(call-next-method))))
-
- (defmethod undo :around ((window window))
- (if (ccl::editing-dialogs-p window)
- (funcall (cdr *dialog-change-undohook*))
- (when (next-method-p)(call-next-method))))
-
-
- (defmethod window-can-do-operation :around ((window window) op &optional item)
- (cond
- ((ccl::editing-dialogs-p window)
- (case op
- (undo
- (when *dialog-change-undohook*
- (set-menu-item-title item (car *dialog-change-undohook*))
- t))
- (select-all
- (dialog-items window))
- ((clear copy cut) *selected-dialog-items*)
- (paste *dialog-item-scrap*)))
- ((next-method-p)(call-next-method))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; definitions and redefinitions for dialog-items
- ;;
-
- (defvar *dialog-item-editor-hash* (make-hash-table :test 'eq :weak t))
-
- (defun get-dialog-item-editor (item)
- (gethash item *dialog-item-editor-hash*))
-
- (defun (setf get-dialog-item-editor) (editor item)
- (if editor
- (setf (gethash item *dialog-item-editor-hash*) editor)
- (remhash item *dialog-item-editor-hash*))
- editor)
-
- (defun dialog-item-selected-p (item)
- (member item *selected-dialog-items* :test #'eq))
-
- (defmethod remove-view-from-window :around ((item dialog-item))
- (when (dialog-item-selected-p item)
- (unselect-dialog-item (view-container item) item))
- (call-next-method))
-
- (defmethod (setf wptr) :around (new-wptr (item dialog-item))
- (when (null new-wptr)
- (let* ((my-ed (get-dialog-item-editor item)))
- (when my-ed
- (window-close my-ed)
- (setf (get-dialog-item-editor item) nil))))
- (call-next-method))
-
- ; Patch the method for simple-view
- (defmethod view-contains-point-p ((item dialog-item) point)
- (let* ((offset (if (ccl::editing-dialogs-p (view-container item)) 3 0))
- (point-h (point-h point))
- (point-v (point-v point))
- (item-p (view-position item))
- (item-s (view-size item))
- (item-left (- (point-h item-p) offset))
- (item-right (+ offset offset
- item-left (point-h item-s))))
- (when (< item-left point-h item-right)
- (let*
- ((item-top (- (point-v item-p) offset))
- (item-bottom (+ offset offset
- item-top (point-v item-s))))
- (< item-top point-v item-bottom)))))
-
- (defmethod new-action-from-dialog ((item dialog-item))
- (let ((*save-definitions* t))
- (setf (dialog-item-action-function item)
- (eval (read-from-string
- (get-text-from-user
- "Please enter text for the dialog-item-action:"
- (dialog-item-action-source item)))))))
-
- (defmethod dialog-item-action-source ((item dialog-item) &aux old-source)
- (let* ((*print-pretty* t))
- (format nil
- "(function~% ~a)"
- (let ((f (dialog-item-action-function item)))
- (if f
- (or (and (setq old-source (uncompile-function f))
- (format nil "~s" old-source))
- " (lambda (item)
- ;The previous source code for the action could not be found.
- ;Perhaps the code for the dialog was loaded from a fasl file,
- ;or was compiled with *save-definitions* bound to nil
- )")
- " (lambda (item)
- item
- ;Enter action source code here.
- )")))))
-
- (defmethod set-item-nick-name ((item dialog-item))
- (let ((new-name (read-from-string
- (get-string-from-user "Enter a nick-name for the item."
- :initial-string (string (or (view-nick-name item)
- ""))))))
- (set-view-nick-name item new-name)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; support for moving and resizing windows
- ;;
-
-
- (defmethod grow-or-move-window ((window window) where)
- (if (double-click-p)
- (edit-dialog window) ;code for this is down at the bottom
- (let* ((wptr (wptr window))
- (global-where (ccl::%local-to-global wptr where))
- (w-size (view-size window)))
- (reset-selected-item-list window)
- (if (and (> 15 (- (point-h w-size)
- (point-h where)))
- (> 15 (- (point-v w-size)
- (point-v where))))
- (grow-window window)
- (progn
- (#_DragWindow :ptr wptr
- :long global-where
- :ptr (window-drag-rect window)))))))
-
- (defmethod grow-window ((window window) &aux (pos (view-position window)))
- (set-view-size window
- (subtract-points (grow-gray-rect pos
- (view-size window)
- (window-manager-port)
- 45)
- pos)))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; support for guides
- ;;
-
-
- (defmethod draw-dialog-guides ((window window))
- (let* ((w-size (view-size window))
- (w-height (point-v w-size))
- (w-width (point-h w-size)))
- (with-focused-view window
- (with-pen-saved
- (#_PenMode :word (position :patxor *pen-modes*))
- (#_PenPat :ptr *gray-pattern*)
- (dolist (guide (get-vertical-guides window))
- (draw-one-guide window :vertical guide w-height))
- (dolist (guide (get-horizontal-guides window))
- (draw-one-guide window :horizontal guide w-width))))))
-
- (defmethod draw-one-guide ((window window) direction position end)
- "port, pattern, and mode must already be set"
- (case direction
- (:vertical
- (#_MoveTo :word position
- :word 0)
- (#_LineTo :word position
- :word end))
- (:horizontal
- (#_MoveTo :word 0
- :word position)
- (#_LineTo :word end
- :word position))
- (t (error "bad argument: ~s " direction))))
-
- (defmethod add-guide ((window window) direction)
- (draw-dialog-guides window)
- (unwind-protect
- (case direction
- (:vertical
- (push 50 (get-vertical-guides window)))
- (:horizontal
- (push 50 (get-horizontal-guides window)))
- (t (error "bad argument: ~s " direction)))
- (draw-dialog-guides window)))
-
- (defmethod add-horizontal-guide ((window window))
- (add-guide window :horizontal))
-
- (defmethod add-vertical-guide ((window window))
- (add-guide window :vertical))
-
- (defmethod drag-guide ((window window) where
- &aux guide direction end extractor)
- (let ((horizontal-guides (get-horizontal-guides window))
- (vertical-guides (get-vertical-guides window)))
- (cond
- ((setq guide
- (car (memq (point-h where) vertical-guides)))
- (setq vertical-guides
- (setf (get-vertical-guides window) (delete guide vertical-guides))
- direction :vertical
- end (point-v (view-size window))
- extractor #'point-h))
- ((setq guide
- (car (memq (point-v where) horizontal-guides)))
- (setq horizontal-guides
- (setf (get-horizontal-guides window) (delete guide horizontal-guides))
- direction :horizontal
- end (point-h (view-size window))
- extractor #'point-v))
- (t (error "bad argument: ~s " where)))
- (with-focused-view window
- (with-pen-saved
- (#_PenMode :word (position :patxor *pen-modes*))
- (#_PenPat :ptr *gray-pattern*)
- (do* ((old-mouse (funcall extractor where)
- new-mouse)
- (new-mouse old-mouse
- (funcall extractor (view-mouse-position window))))
- ((not (mouse-down-p))
- (when (> old-mouse 0)
- (if (eq direction :vertical)
- (when (< old-mouse (point-h (view-size window)))
- (setf (get-vertical-guides window)
- (push old-mouse vertical-guides)))
- (when (< old-mouse (point-v (view-size window)))
- (setf (get-horizontal-guides window)
- (push old-mouse horizontal-guides))))))
- (draw-one-guide window direction old-mouse end)
- (draw-one-guide window direction new-mouse end)
- (sleep 1/60))))))
-
- (defmethod guide-align ((window window) point)
- (let* ((h (point-h point))
- (v (point-v point)))
- (when (setq point
- (car (member h (get-vertical-guides window) :test #'on-guide-p)))
- (setq h point))
- (when (setq point
- (car (member v (get-horizontal-guides window) :test #'on-guide-p)))
- (setq v point))
- (make-point h v)))
-
- (defun on-guide-p (num-1 num-2)
- (<= (abs (- num-1 num-2)) *guide-gravity*))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; support for selecting/moving/resizing dialog items
- ;;
-
-
- (defmethod select-dialog-item ((window window) item)
- (pushnew item *selected-dialog-items*)
- (with-focused-view window
- (highlight-one-selected-item window item t)))
-
- (defmethod unselect-dialog-item ((window window) item)
- (setq *selected-dialog-items*
- (delete item *selected-dialog-items*))
- (with-focused-view window
- (highlight-one-selected-item window item nil)))
-
- (defmethod reset-selected-item-list ((window window))
- (highlight-selected-items window nil)
- (setq *selected-dialog-items* nil))
-
- (defmethod highlight-selected-items ((window window) on-p &optional draw-p)
- (with-focused-view window
- (dolist (item *selected-dialog-items*)
- (highlight-one-selected-item window item on-p draw-p))))
-
- (defmethod highlight-one-selected-item ((window window) item on-p &optional draw-p)
- "port should already be set"
- (declare (optimize (speed 3) (safety 0)))
- (declare (special on-p draw-p)) ; temporary until stack-consed closures
- (let* (pos size end)
- (setq pos (view-position item)
- size (view-size item)
- end (add-points pos size))
- (let* ((delta 3)
- (top (point-v pos))
- (top-top (- top delta))
- (bottom (point-v end))
- (bottom-bottom (+ bottom delta))
- (left (point-h pos))
- (left-left (- left delta))
- (right (point-h end))
- (right-right (+ right delta))
- (left-center (+ 1 left-left (ash (point-h size) -1)))
- (right-center (+ left-center delta))
- (top-center (+ 1 top-top (ash (point-v size) -1)))
- (bottom-center (+ top-center delta)))
- (declare (fixnum delta top top-top bottom bottom-bottom
- left left-left right right-right
- left-center right-center top-center bottom-center))
- (rlet ((rect :rect))
- (declare (special rect)) ; temporary until stack-consed closures
- (flet ((do-rect (top bottom left right)
- (rset rect rect.top top)
- (rset rect rect.left left)
- (rset rect rect.bottom bottom)
- (rset rect rect.right right)
- (if on-p
- (if draw-p
- (#_PaintRect :ptr rect)
- (#_InvalRect :ptr rect))
- (progn
- (invalidate-corners
- window
- (make-point left top)
- (make-point right bottom)
- t)))))
- (declare (dynamic-extent do-rect))
- (do-rect top-top top left-left left)
- (do-rect top-top top left-center right-center)
- (do-rect top-top top right right-right)
- (do-rect top-center bottom-center left-left left)
- (do-rect top-center bottom-center right right-right)
- (do-rect bottom bottom-bottom left-left left)
- (do-rect bottom bottom-bottom left-center right-center)
- (do-rect bottom bottom-bottom right right-right))))))
-
- (defmethod select-several-items ((window window) where &aux scratch)
- (unless (shift-key-p)
- (reset-selected-item-list window))
- (rlet ((user-rect :rect)
- (scratch-rect :rect)
- (i-rect :rect))
- (#_pt2rect :long where
- :long (grow-gray-rect where 0 (wptr window) nil)
- :ptr user-rect)
- (dolist (item (dialog-items window))
- (setq scratch (view-position item))
- (rset i-rect :rect.topleft scratch)
- (rset i-rect :rect.bottomright (add-points
- scratch
- (view-size item)))
- (#_SectRect :ptr user-rect :ptr i-rect :ptr scratch-rect)
- (unless (#_EmptyRect :ptr scratch-rect :boolean)
- (select-dialog-item window item)))))
-
- (defmethod grow-or-move-dialog-item ((window window) where item was-selected)
- (while (eq where (view-mouse-position window))
- (unless (mouse-down-p)
- (if was-selected
- (unselect-dialog-item window item)
- (select-dialog-item window item))
- (return-from grow-or-move-dialog-item)))
- (select-dialog-item window item)
- (let* (pos end)
- (setq pos (view-position item)
- end (add-points pos (view-size item)))
- (rlet ((item-rect :rect
- :topleft pos
- :bottomright end))
- (unwind-protect
- (progn
- (#_HideCursor)
- (if (or (#_PtInRect where item-rect)
- (> (length *selected-dialog-items*) 1))
- (move-selected-dialog-items window where item-rect)
- (grow-dialog-item window item item-rect where)))
- (#_ShowCursor)))))
-
- (defmethod grow-dialog-item ((window window) item item-rect where &aux new-pos)
- (highlight-one-selected-item window item nil)
- (let* ((old-pos (rref item-rect :rect.topleft))
- (old-size (subtract-points
- (rref item-rect :rect.bottomright)
- old-pos)))
- (setq item-rect
- (grow-item-outline window item-rect where))
- (without-interrupts
- (invalidate-view item t)
- (set-view-position item (setq new-pos
- (rref item-rect :rect.topleft)))
- (set-view-size item (subtract-points
- (rref item-rect :rect.bottomright)
- new-pos)))
- (highlight-one-selected-item window item t)
- (setq *dialog-change-undohook*
- (cons "Undo Resize"
- #'(lambda ()
- (with-focused-view window
- (without-interrupts
- (highlight-one-selected-item window item nil)
- (set-view-size item old-size)
- (set-view-position item old-pos)
- (highlight-one-selected-item window item t))))))))
-
- (defmethod grow-item-outline ((window window) rect where)
- "destructively modifies the rect"
- (let* ((flag nil)
- (pos where)
- (pos-h (point-h pos))
- (pos-v (point-v pos))
- (top (+ (rref rect :rect.top) 3))
- (left (+ (rref rect :rect.left) 3))
- (bottom (- (rref rect :rect.bottom) 3))
- (right (- (rref rect :rect.right) 3))
- (min-v (+ top 2))
- (min-h (+ left 2))
- (max-v (- bottom 2))
- (max-h (- right 2)))
- (setq flag
- (cond ((< pos-h left) ;on left side
- (cond
- ((< pos-v top) (setq min-h -4095 min-v -4095) :topleft)
- ((> pos-v bottom) (setq min-h -4095 max-v 4095) :bottomleft)
- (t (setq min-h -4095 min-v 0 max-v 0) :left)))
- ((> pos-h right) ;on right side
- (cond
- ((< pos-v top) (setq max-h 4095 min-v -4095) :topright)
- ((> pos-v bottom) (setq max-h 4095 max-v 4095) :bottomright)
- (t (setq max-h 4095 min-v 0 max-v 0) :right)))
- (t ;in the middle
- (cond ((< pos-v top) (setq min-v -4095 min-h 0 max-h 0) :top)
- (t (setq max-v 4095 min-h 0 max-h 0) :bottom)))))
- (with-focused-view window
- (with-pen-saved
- (with-clip-rect (rref (wptr window) :grafport.portrect)
- (#_PenMode :word (position :patxor *pen-modes*))
- (#_PenPat :ptr *gray-pattern*)
- (#_FrameRect :ptr rect)
- (setq pos (make-point (max min-h (min max-h (point-h pos)))
- (max min-v (min max-v (point-v pos)))))
- (do* ((old-mouse pos new-mouse)
- (new-mouse pos (view-mouse-position window)))
- ((not (mouse-down-p)))
- (setq new-mouse (make-point (max min-h (min max-h (point-h new-mouse)))
- (max min-v (min max-v (point-v new-mouse)))))
- (unless (eq old-mouse new-mouse)
- (#_FrameRect :ptr rect)
- (update-rect flag rect (subtract-points new-mouse old-mouse))
- (#_FrameRect :ptr rect)))
- (#_FrameRect :ptr rect)
- rect)))))
-
- (defun update-rect (flag rect delta)
- (case flag
- (:left (rset rect :rect.left (+ (rref rect :rect.left) (point-h delta))))
- (:right (rset rect :rect.right (+ (rref rect :rect.right) (point-h delta))))
- (:top (rset rect :rect.top (+ (rref rect :rect.top) (point-v delta))))
- (:bottom (rset rect :rect.bottom (+ (rref rect :rect.bottom) (point-v delta))))
- (:topleft (update-rect :top rect delta) (update-rect :left rect delta))
- (:bottomright (update-rect :bottom rect delta) (update-rect :right rect delta))
- (:topright (update-rect :top rect delta) (update-rect :right rect delta))
- (:bottomleft (update-rect :bottom rect delta) (update-rect :left rect delta))))
-
- (defmethod move-selected-dialog-items ((window window) where total-rect &aux
- (item-old-pos-a-list ())
- (constrained (shift-key-p))
- (wptr (wptr window))
- reg pos)
- (when (option-key-p)
- (duplicate-selected-dialog-items window))
- (rlet ((one-rect :rect))
- (dolist (item *selected-dialog-items*)
- (highlight-one-selected-item window item nil)
- (rset one-rect :rect.topleft (setq pos (view-position item)))
- (rset one-rect :rect.bottomright (add-points pos (view-size item)))
- (#_UnionRect :ptr one-rect
- :ptr total-rect
- :ptr total-rect)
- (push (cons item pos) item-old-pos-a-list)))
- (setq constrained
- (if constrained
- (if (eq (point-h where) (point-h (view-mouse-position window)))
- 2 ;vertical constraint
- 1) ;horizontal constraint
- 0))
- (unwind-protect
- (progn
- (setq reg (#_NewRgn :ptr))
- (#_RectRgn :ptr reg :ptr total-rect)
- (rlet ((slop-rect :rect))
- (copy-record (rref wptr windowRecord.portrect) :rect slop-rect)
- (#_InsetRect :ptr slop-rect :word -10 :word -10)
- (setq pos
- (#_DragGrayRgn :ptr reg
- :long where
- :ptr (rref wptr windowRecord.portrect)
- :ptr slop-rect
- :word constrained
- :ptr (ccl::%null-ptr)
- :long))))
- (when reg
- (#_DisposeRgn :ptr reg)
- (unless (eql -32768 (point-h pos)) ;some Mac magic number. should be an equate
- (setq pos (best-guide-delta window total-rect pos))
- (dolist (item *selected-dialog-items*)
- (without-interrupts
- (set-view-position item (add-points pos (view-position item)))
- (invalidate-view item)
- (highlight-one-selected-item window item t)))
- (setq *dialog-change-undohook*
- (cons "Undo Move"
- #'(lambda ()
- (reset-selected-item-list window)
- (dolist (item/pos item-old-pos-a-list)
- (set-view-position (car item/pos) (cdr item/pos))
- (select-dialog-item window (car item/pos))))))))))
-
- (defmethod best-guide-delta ((window window) rect delta)
- (let* ((topleft (add-points delta (rref rect :rect.topleft)))
- (bottomright (add-points delta (rref rect :rect.bottomright)))
- (new-tl topleft)
- (new-br bottomright)
- (new-delta-h (point-h delta))
- (new-delta-v (point-v delta))
- temp1
- temp2)
- (setq topleft (guide-align window topleft))
- (setq bottomright (guide-align window bottomright))
- (if (neq (setq temp1 (point-v topleft))
- (setq temp2 (point-v new-tl)))
- (setq new-delta-v (+ new-delta-v (- temp1 temp2)))
- (when (neq (setq temp1 (point-v bottomright))
- (setq temp2 (point-v new-br)))
- (setq new-delta-v (+ new-delta-v (- temp1 temp2)))))
- (if (neq (setq temp1 (point-h topleft))
- (setq temp2 (point-h new-tl)))
- (setq new-delta-h (+ new-delta-h (- temp1 temp2)))
- (when (neq (setq temp1 (point-h bottomright))
- (setq temp2 (point-h new-br)))
- (setq new-delta-h (+ new-delta-h (- temp1 temp2)))))
- (make-point new-delta-h new-delta-v)))
-
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; code for adding dialog-items
- ;;
-
-
- (defmethod duplicate-selected-dialog-items ((window window))
- (let ((new-items (copy-selected-dialog-items window)))
- (reset-selected-item-list window)
- (apply #'add-subviews window new-items)
- (dolist (item new-items)
- (select-dialog-item window item))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; item selection palette
- ;;
-
- (defmethod initialize-instance ((palette item-palette) &rest initargs &key
- (window-show t))
- (declare (dynamic-extent initargs))
- (apply #'call-next-method
- palette
- :window-show nil
- :view-size *item-palette-size*
- :view-position *item-palette-position*
- initargs)
- (apply #'add-subviews
- palette
- *prototype-dialog-items*)
- (when window-show
- (window-show palette))
- (setq *current-item-palette* palette))
-
- (defmethod install-view-in-window :after (view (palette item-palette))
- (let* ((size (view-size palette))
- (view-br (add-points (view-position view) (view-size view)))
- (max-h (max (point-h size) (+ 5 (point-h view-br))))
- (max-v (max (point-v size) (+ 5 (point-v view-br)))))
- (unless (eql size (setq size (make-point max-h max-v)))
- (set-view-size palette size))))
-
- (defmethod ccl::view-find-vacant-position ((palette item-palette) subview)
- (let ((total-rgn (#_NewRgn))
- (rgn (#_NewRgn))
- (size (view-size palette))
- (subview-size (view-size subview)))
- (unless (>= (point-v size) (point-v subview-size))
- (setq size (set-view-size palette (point-h size) (+ 10 (point-v subview-size)))))
- (unwind-protect
- (progn
- (dolist (view (subviews palette))
- (unless (eq view subview)
- (multiple-value-bind (tl br) (view-corners view)
- (#_SetRectRgn :ptr rgn :long tl :long br)
- (#_UnionRgn rgn total-rgn total-rgn))))
- (let ((pos (call-next-method)))
- (#_SetRectRgn :ptr rgn :long pos :long (add-points pos (view-size subview)))
- (#_SectRgn rgn total-rgn rgn)
- (if (#_EmptyRgn rgn)
- pos
- (progn
- (setf (slot-value subview 'view-position) pos)
- (set-view-size palette
- (max (point-h size) (+ 5 (point-h subview-size)))
- (+ (href total-rgn :region.rgnbbox.bottom) (point-v subview-size) 15))
- (setf (slot-value subview 'view-position) nil)
- (call-next-method)))))
- (#_DisposeRgn rgn)
- (#_DisposeRgn total-rgn))))
-
- (defmethod window-close-event-handler ((palette item-palette))
- (use-dialogs))
-
- (defmethod window-close :before ((palette item-palette))
- (setq *current-item-palette* nil)
- (setq *item-palette-position* (view-position palette)
- *item-palette-size* (view-size palette)))
-
- (defmethod view-click-event-handler ((palette item-palette) where)
- (let* ((item (find-view-containing-point palette where nil t)))
- (when item
- (select-and-add-dialog-item palette item where))))
-
- (defmethod select-and-add-dialog-item ((palette item-palette) item mouse-pos)
- (declare (optimize (debug 3)))
- (let* ((offset (view-position palette))
- (topleft (add-points offset (view-position item)))
- (bottomright (add-points topleft (view-size item)))
- (reg (#_NewRgn :ptr))
- (wmgrPort (window-manager-port))
- mouse-offset)
- (setq mouse-pos (add-points mouse-pos offset)
- mouse-offset (subtract-points mouse-pos topleft))
- (unwind-protect
- (with-port wmgrPort
- (rlet ((rect :rect
- :topleft topleft
- :bottomright bottomright))
- (#_RectRgn :ptr reg :ptr rect) ;get a region of the item outline
- (with-macptrs ((visrgn (rref wmgrPort :grafport.visrgn)))
- (setf (rref rect :rect.topleft) (rref visrgn :region.rgnBbox.topLeft))
- (setf (rref rect :rect.bottomright) (rref visrgn :region.rgnbbox.botRight)))
- (with-clip-rect rect
- (let* ((pos (add-points mouse-pos (#_DragGrayRgn :ptr reg
- :long mouse-pos
- :ptr rect
- :ptr rect
- :word 0 ;not constrained
- :ptr (ccl::%null-ptr)
- :long)))
- (window (front-window))
- (wpos (view-position window))
- (size (add-points wpos (view-size window))))
- (when (and (ccl::editing-dialogs-p window)
- (point>= pos wpos)
- (point< pos size))
- (add-subviews
- window
- (make-instance (type-of item)
- :dialog-item-text "Untitled"
- :view-position (subtract-points
- (subtract-points pos wpos)
- mouse-offset))))))))
- (#_DisposeRgn :ptr reg)))
- (menu-update *edit-menu*))
-
-
- (defun point< (pt1 pt2)
- (and (< (point-h pt1) (point-h pt2))
- (< (point-v pt1) (point-v pt2))))
-
- (defun point>= (pt1 pt2)
- (and (>= (point-h pt1) (point-h pt2))
- (>= (point-v pt1) (point-v pt2))))
-
-
- (defun add-editable-dialog-item (proto-item)
- (let* ((class (class-of proto-item)))
- (when (member class *prototype-dialog-items* :key #'class-of)
- (remove-editable-dialog-item class))
- (push proto-item *prototype-dialog-items*)
- (when *current-item-palette*
- (add-subviews *current-item-palette* proto-item))))
-
- (defun remove-editable-dialog-item (class)
- (let* ((item (find class *prototype-dialog-items* :key #'class-of)))
- (when item
- (setq *prototype-dialog-items*
- (delete item *prototype-dialog-items*))
- (when *current-item-palette*
- (remove-subviews *current-item-palette* item))
- (setf (slot-value item 'view-position) nil))))
-
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; dialog for creating new dialog windows
- ;;
-
-
- (defmethod dialog-item-action :before ((button frame-window-r-b))
- (dialog-item-enable (find-named-sibling button 'item-close-box)))
-
- (defmethod dialog-item-action :before ((button box-window-r-b))
- (let ((close-box (find-named-sibling button 'item-close-box)))
- (check-box-uncheck close-box)
- (dialog-item-disable close-box)))
-
- (defun create-new-dialog ()
- (let* ((options nil))
- (setq options
- (modal-dialog
- (make-instance
- 'dialog
- :window-type :double-edge-box
- :window-title "Untitled Dialog"
- :view-position '(:top 100)
- :view-size #@(342 165)
- :window-show nil
- :view-subviews
- (list
- (make-dialog-item 'static-text-dialog-item
- #@(3 3) #@(206 18)
- "Select Dialog Window Options:")
- (make-dialog-item 'button-dialog-item
- #@(190 140) #@(62 16) "OK"
- #'(lambda (item)
- (let ((dialog (view-container item)))
- (return-from-modal-dialog
- (list
- (check-box-checked-p
- (view-named 'item-color-window dialog))
- (dialog-item-attribute
- (pushed-radio-button dialog))
- (check-box-checked-p
- (view-named 'item-close-box dialog))))))
- :default-button t)
- (make-dialog-item 'button-dialog-item
- #@(269 140) #@(62 16) "Cancel"
- #'(lambda (item)
- (declare (ignore item))
- (return-from-modal-dialog :cancel)))
- (make-dialog-item 'check-box-dialog-item
- #@(4 117) #@(139 17) "Include Close Box" nil
- :check-box-checked-p t
- :view-nick-name 'item-close-box)
- (make-dialog-item 'check-box-dialog-item
- #@(4 140) #@(139 16) "Color Window" nil
- :view-nick-name 'item-color-window)
- (make-dialog-item 'frame-window-r-b
- #@(4 26) #@(94 16) "Document" nil
- :radio-button-pushed-p t
- :attribute :document)
- (make-dialog-item 'frame-window-r-b
- #@(4 49) #@(163 16) "Document with Grow" nil
- :attribute :document-with-grow)
- (make-dialog-item 'frame-window-r-b
- #@(4 71) #@(163 16) "Document with Zoom" nil
- :attribute :document-with-zoom)
- (make-dialog-item 'frame-window-r-b
- #@(4 93) #@(72 16) "Tool" nil
- :attribute :tool)
- (make-dialog-item 'box-window-r-b
- #@(190 25) #@(133 17) "Single Edge Box" nil
- :attribute :single-edge-box)
- (make-dialog-item 'box-window-r-b
- #@(190 49) #@(130 16) "Double Edge Box" nil
- :attribute :double-edge-box)
- (make-dialog-item 'box-window-r-b
- #@(190 71) #@(134 16) "Shadow Edge Box" nil
- :attribute :shadow-edge-box)))))
- (make-instance (if (pop options)
- 'color-dialog
- 'dialog)
- :window-type (pop options)
- :close-box-p (pop options)
- :view-size #@(300 150)
- :view-position '(:top 60))))
-
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;;
- ;; code for editing features of a dialog
- ;;
-
- (defmethod edit-dialog ((window window))
- (modal-dialog
- (make-instance 'dialog-editor
- :dialog window)))
-
-
- (defmethod initialize-instance ((editor dialog-editor) &rest initargs &key dialog)
- (declare (dynamic-extent initargs))
- (apply #'call-next-method
- editor
- :window-title (format nil "~s Dialog" (window-title dialog))
- initargs)
- (add-control-items editor dialog)
- (add-attribute-items editor dialog))
-
- (defmethod add-control-items ((editor dialog-editor) dialog)
- (declare (ignore dialog))
- (add-subviews
- editor
- (make-dialog-item 'button-dialog-item
- #@(247 42) #@(50 16) "OK"
- #'(lambda (item &aux new-pos title)
- (let* ((editor (view-container item))
- (dialog (dialog-editor-dialog editor)))
- (setq new-pos
- (read-from-string
- (dialog-item-text
- (view-named 'item-view-position editor)))
- title
- (dialog-item-text
- (view-named 'item-title editor)))
- (set-window-title dialog title)
- (set-view-position dialog new-pos))
- (return-from-modal-dialog t))
- :default-button t)
- (make-dialog-item 'button-dialog-item
- #@(310 42) #@(50 16) "Cancel"
- #'(lambda (item)
- (declare (ignore item))
- (return-from-modal-dialog :cancel)))))
-
- (defmethod add-attribute-items ((editor dialog-editor) dialog)
- (let* ((the-pos (window-centered-p dialog)))
- (when (fixnump the-pos) (setq the-pos (ppoint the-pos)))
- (add-subviews
- editor
- (make-dialog-item 'static-text-dialog-item
- #@(7 11) #@(92 15) "Window Title:")
- (make-dialog-item 'editable-text-dialog-item
- #@(104 11) #@(252 16) (window-title dialog) nil
- :allow-returns nil
- :view-nick-name 'item-title)
- (make-dialog-item 'static-text-dialog-item
- #@(7 42) #@(130 16) "Window Position:" nil)
- (make-dialog-item 'editable-text-dialog-item
- #@(130 42) #@(105 16) (let ((*print-base* 10))
- (format nil "~s" the-pos)) nil
- :view-nick-name 'item-view-position))))
-